class Middleware {
    constructor(name, next) {
        this.name = name;
        this.nextFn = next;
    }

    checkNext() {
        let seed = parseInt(Math.random() * 10);
        console.log(`${this.name}执行校验`, seed);
        seed > 3 && this.nextFn();
    }
}

class App {
    constructor() {
        this.name = "app";
        this.mds = {};
        this.hasNext = false;
    }

    use(url, mdnames, ...tasks) {
        this.mds[url] = this.mds[url] || [];
        mdnames.forEach((name) => {
            this.mds[url].push(new Middleware(name, this.next.bind(this)));
        });
        // console.log("this.mds[url] after push mds",this.mds[url]);
        tasks.forEach((task) => this.mds[url].push(task));
    }

    next() {
        console.log(this.name, "next被调用了");
        this.hasNext = true;
    }

    handleRequest(url, req, data) {
        for (let i = 0; i < this.mds[url].length; i++) {
            const md = this.mds[url][i];

            /* 通过校验则执行任务 */
            this.hasNext = false;
            if (md instanceof Middleware) {
                md.checkNext();
            } else {
                md.apply(this, [req, data, this.next.bind(this)]);
            }

            if (!this.hasNext) {
                break;
            }
        }

        console.log("game over!");
    }
}

function main() {
    const app = new App();

    app.use(
        "/api/one",
        ["LoginChecker", "PaymentChecker", "ScoreChecker"],
        (req, data, next) => {
            console.log("业务11被执行了", req, data, next);
            // next();
        },
        (req, data, next) => {
            console.log("业务12被执行了", req, data, next);
            next();
        },
        (req, data, next) => {
            console.log("业务13被执行了", req, data, next);
            next();
        }
    );

    app.use(
        "/api/two",
        ["LoginChecker", "PaymentChecker"],
        (req, data, next) => {
            console.log("业务21被执行了", req, data);
            next();
        },
        (req, data, next) => {
            console.log("业务22被执行了", req, data);
            next();
        }
    );

    app.handleRequest("/api/one", "请求对象", "请求数据");
}

main();
